#ifndef     __CAN_RECEIVER_H
#define     __CAN_RECEIVER_H

#include "./can_frame.h"
#include "./conn_info.h"
#include <string.h>

namespace conn {

template <typename RecvCompleteHandler>
class CanReceiver {
    static constexpr uint32_t MAX_PKG_SIZE = 128;

private:
    uint8_t m_frame_id;
    uint8_t m_data_buf[MAX_PKG_SIZE];
    uint8_t m_recv_index;

public:
    void recv(const CANFrame &frame) {
        uint8_t id = frame.frame_id();
        if (id == 0) {
            m_recv_index = 0;
            m_frame_id = 0;
        }

        if (m_frame_id != id) {
            // error 
            static_cast<RecvCompleteHandler *>(this)->on_id_invalid();
            return;
        }
        if ((m_recv_index + frame.len) > MAX_PKG_SIZE) {
            // error 
            static_cast<RecvCompleteHandler *>(this)->on_much_data();
            return;
        }

        memcpy(m_data_buf + m_recv_index, frame.buf, frame.len);
        m_recv_index += frame.len;
        m_frame_id ++;

        if (!frame.is_complete()) {
            return;
        }
        ConnInfo conn_info = ConnInfo::from_can_id(frame.ext_id());
        static_cast<RecvCompleteHandler *>(this)->on_recv_complete(conn_info, m_data_buf, m_recv_index);
        m_recv_index = 0;
    }
};


}



#endif
